home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / keybind / codehelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  17.3 KB  |  682 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef VARARGS
  4. #  include <varargs.h>
  5. #else
  6. #  include <stdarg.h>
  7. #endif
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12.  
  13. #define CODEHELP_C
  14.  
  15. #include "keybind.h"
  16. #include <lib/ori_add_lib.h>
  17. /*}}}  */
  18.  
  19. /*{{{  variables*/
  20. public boolean new_vars_enabled=False;
  21. private int dv_list[int_dummy_vars];
  22. private boolean dv_init=False;
  23. /*}}}  */
  24.  
  25. /*{{{  mstrcpy*/
  26. public unsigned char *mstrcpy(unsigned char const * const s)
  27. {
  28.   unsigned char *x;
  29.  
  30.   x=kbd_malloc(ustrlen(s)+1);
  31.   ustrcpy(x,s);
  32.  
  33.   return(x);
  34. }
  35. /*}}}  */
  36. /*{{{  m_error_po*/
  37. public void m_error_po(char const * const m)
  38. {
  39.   error_po();
  40.   fputs(m,stderr);
  41. }
  42. /*}}}  */
  43. /*{{{  m_exit*/
  44. #ifdef VARARGS
  45.    public void m_exit(format,va_alist)char const * const format;va_dcl
  46. #else
  47.    public void m_exit(char const * const format,...)
  48. #endif
  49. { va_list ap;
  50.  
  51.   error_po();
  52.   /*{{{  start arglist handling*/
  53. #  ifdef VARARGS
  54.      va_start(ap);
  55. #  else
  56.      va_start(ap,format);
  57. #  endif
  58.   /*}}}  */
  59.   vfprintf(stderr,(char*)format,ap);
  60.   /*{{{  end arglist handling*/
  61.   va_end(ap);
  62.   /*}}}  */
  63.   kbd_exit(1);
  64. }
  65. /*}}}  */
  66. /*{{{  begin_parse*/
  67. public void begin_parse(void)
  68. {
  69.   if (get_single_token()!=BEGIN)
  70.      m_exit(M_WANTBEGIN);
  71. }
  72. /*}}}  */
  73. /*{{{  end_parse*/
  74. public void end_parse(char const * const er)
  75. {
  76.   if (get_single_token()!=END)
  77.      m_exit(er);
  78. }
  79. /*}}}  */
  80. /*{{{  name_parse*/
  81. public void name_parse
  82.  ( unsigned char *str,
  83.    char const * const er,
  84.    boolean const op
  85.  )
  86. {
  87.   switch (get_full_token())
  88.    { case OPCODE:
  89.      case OPERATION:
  90.      case VARIABLE:
  91.         if (op)
  92.          {
  93.      case NAME:
  94.            ustrcpy(str,tk_string);
  95.            return;
  96.          }
  97.      default:
  98.         m_exit(er);
  99.    }
  100. }
  101. /*}}}  */
  102. /*{{{  name_to_var transform token NAME to token VARIABLE, if possible*/
  103. public tokens name_to_var(tokens token, int size, boolean newvars)
  104. { if (token==NAME && newvars)
  105.    { creat_var(tk_string,size,-1);
  106.      for (tk_var=var_list;tk_var;tk_var=tk_var->next)
  107.         if (!ustrcmp(tk_var->var_name,tk_string))
  108.            break;
  109.      token=VARIABLE;
  110.    }
  111.   if (token==VARIABLE && size && size!=tk_var->size)
  112.      m_exit(M_NOVAR);
  113.   return(token);
  114. }
  115. /*}}}  */
  116. /*{{{  put variable-adress*/
  117. public TOKEN *put_var(TOKEN *buff)
  118. {
  119.  
  120.   switch (name_to_var(get_full_token(),1,new_vars_enabled))
  121.    { case VARIABLE:
  122.         *buff++ = (TOKEN) tk_var->no;
  123.         if (tk_var->size==1)
  124.            break;
  125.      default:
  126.         m_exit(M_NOVAR);
  127.    }
  128.   return(buff);
  129. }
  130. /*}}}  */
  131. /*{{{  dummy_var*/
  132. public int dummy_var(int no)
  133. {
  134.   /*{{{  maybe init it*/
  135.   if (!dv_init)
  136.    { int i;
  137.      for (i=0;i<int_dummy_vars;dv_list[i++]= -1);
  138.      dv_init=True;
  139.    }
  140.   /*}}}  */
  141.   /*{{{  no dummy-vars available -> error*/
  142.   if (no>=int_dummy_vars)
  143.      m_exit(M_NOVAS);
  144.   /*}}}  */
  145.   if (dv_list[no]==-1)
  146.    { unsigned char s[10];
  147.  
  148.      sprintf((char*)s,"(dummy%d)",no);
  149.      return(dv_list[no]=creat_var(s,1,-1));
  150.    }
  151.   else
  152.      return(dv_list[no]);
  153. }
  154. /*}}}  */
  155. /*{{{  macro-argument variable handling*/
  156. private int ocl_arg_vars[ocl_max_args];
  157. private int ocl_loc_vars[ocl_max_args];
  158. private int ocl_args_used=0;
  159.  
  160. /*{{{  def_ocl_args*/
  161. public void def_ocl_args(int no)
  162. { while (ocl_args_used<no)
  163.    { unsigned char vn[26];
  164.  
  165.      sprintf((char*)vn,"(arg%d)",ocl_args_used);
  166.      ocl_arg_vars[ocl_args_used]=creat_var(vn,1,-1);
  167.      sprintf((char*)vn,"(loc%d)",ocl_args_used);
  168.      ocl_loc_vars[ocl_args_used]=creat_var(vn,1,-1);
  169.      ocl_args_used++;
  170.    }
  171. }
  172. /*}}}  */
  173. /*{{{  ocl_arg_var*/
  174. public int ocl_arg_var(int no)
  175. {
  176.   if (no>=ocl_args_used)
  177.      m_exit(M_CRASH);
  178.   return(ocl_arg_vars[no]);
  179. }
  180. /*}}}  */
  181. /*{{{  ocl_loc_var*/
  182. public int ocl_loc_var(int no)
  183. {
  184.   if (no>=ocl_args_used)
  185.      m_exit(M_CRASH);
  186.   return(ocl_loc_vars[no]);
  187. }
  188. /*}}}  */
  189. /*}}}  */
  190. /*{{{  isdummy*/
  191. public boolean isdummy(int x)
  192. { int i;
  193.  
  194.   if (dv_init) for (i=0;i<int_dummy_vars;i++) if (dv_list[i]==x) return(True);
  195.   return(False);
  196. }
  197. /*}}}  */
  198. /*{{{  create a jump-command*/
  199. public TOKEN *generate_jmp(TOKEN j, TOKEN *ad, TOKEN *dest)
  200. {
  201.   switch (j)
  202.    { case M_JMP:
  203.      case M_CALL:
  204.      case M_JMP_TRUE:
  205.      case M_JMP_FALSE:
  206.         break;
  207.      default:
  208.         m_exit(M_NOJUMP);
  209.    }
  210.   *ad++ = j;
  211.   *ad= dest-(ad+1);
  212.  
  213.   return(ad+1);
  214. }
  215. /*}}}  */
  216. /*{{{  parse_term*/
  217. /*{{{  destination save register handling*/
  218. typedef struct { int old;int save;boolean changed;boolean chg_use;TOKEN *save_start; } DEST_DAT;
  219.  
  220. /*{{{  start_dest_handle*/
  221. private void start_dest_handle(DEST_DAT *t,int dest,TOKEN **buff,int *dummy_base)
  222. {
  223.   t->save_start= *buff;
  224.   t->old=dest;
  225.   t->save=dummy_var((*dummy_base)++);
  226.   t->changed=t->chg_use=!opt_mac;
  227.   *(*buff)++=M_PUSH_INT;
  228.   *(*buff)++=(TOKEN)dest;
  229.   *(*buff)++=M_POP_INT;
  230.   *(*buff)++=(TOKEN)t->save;
  231. }
  232. /*}}}  */
  233. /*{{{  end_dest_handle*/
  234. private void end_dest_handle(DEST_DAT *t)
  235. { if (!t->chg_use)
  236.    /*{{{  saved target variable not used, so clear these statements*/
  237.    { *(t->save_start)++=O_NOP;
  238.      *(t->save_start)++=O_NOP;
  239.      *(t->save_start)++=O_NOP;
  240.      *(t->save_start)++=O_NOP;
  241.    }
  242.    /*}}}  */
  243. }
  244. /*}}}  */
  245. /*{{{  set_dest*/
  246. private void set_dest(TOKEN *buff,int x,DEST_DAT *t)
  247. { *buff=x;
  248.   if (x==t->old) t->changed=True;
  249. }
  250. /*}}}  */
  251. /*{{{  set_source*/
  252. private void set_source(TOKEN *buff,int x,DEST_DAT *t)
  253. { if (x==t->old && t->changed)
  254.    { *buff=t->save;
  255.      t->chg_use=True;
  256.    }
  257.   else
  258.      *buff=x;
  259. }
  260. /*}}}  */
  261. /*}}}  */
  262.  
  263. /*{{{  recursion for term-parsing*/
  264. public TOKEN *rpt(tokens token,TOKEN *buff,int dest,int dummy,boolean *ret_used,DEST_DAT *t)
  265. { tokens op=name_to_var(token,0,new_vars_enabled);
  266.  
  267.   check_length(buff);
  268.   switch (op)
  269.    { case VARIABLE:
  270.       /*{{{  maybe PUSH new POP old*/
  271.       { int x=tk_var->no;
  272.  
  273.         if (tk_var->size==1)
  274.          /*{{{  handle int var*/
  275.          { if (x!=dest)
  276.             { *buff++=M_PUSH_INT;
  277.               set_source(buff++,x,t);
  278.               *buff++=M_POP_INT;
  279.               set_dest(buff++,dest,t);
  280.             }
  281.          }
  282.          /*}}}  */
  283.         else
  284.          /*{{{  handle int array*/
  285.          { begin_parse();
  286.            op=get_full_token();
  287.            switch(op)
  288.             { case NUMBER:
  289.                  *buff++=M_PUSH_INT;
  290.                  set_source(buff++,x+tk_val,t);
  291.                  *buff++=M_POP_INT;
  292.                  set_dest(buff++,dest,t);
  293.                  break;
  294.               case VARIABLE:
  295.                  if (tk_var->size==1)
  296.                   { *buff++=M_PUSH_INT_X;
  297.                     *buff++=(TOKEN)x;
  298.                     *buff++=(TOKEN)tk_var->no;
  299.                     *buff++=M_POP_INT;
  300.                     set_dest(buff++,dest,t);
  301.                     break;
  302.                   }
  303.               default:
  304.                  if (!(buff=rpt(op,buff,dummy_var(dummy),dummy+1,ret_used,t))) return(0);
  305.                  *buff++=M_PUSH_INT_X;
  306.                  *buff++=(TOKEN)x;
  307.                  *buff++=(TOKEN)dummy_var(dummy);
  308.                  *buff++=M_POP_INT;
  309.                  set_dest(buff++,dest,t);
  310.                  break;
  311.             }
  312.            end_parse(M_WANTEND);
  313.          }
  314.          /*}}}  */
  315.         break;
  316.       }
  317.       /*}}}  */
  318.      case EVAL:
  319.       /*{{{  get value from called macro*/
  320.       { TOKEN *call;
  321.         TOKEN *jmp;
  322.  
  323.         /*{{{  push dummy vars*/
  324.         { int i;
  325.  
  326.           for (i=0;i<dummy;i++)
  327.            { *buff++=M_PUSH_INT;
  328.              *buff++=(TOKEN)dummy_var(i);
  329.            }
  330.         }
  331.         /*}}}  */
  332.         /*{{{  call the macro*/
  333.         buff=generate_jmp(M_CALL,call=buff,buff);
  334.         buff=generate_jmp(M_JMP,jmp=buff,buff);
  335.         generate_jmp(M_CALL,call,buff);
  336.         if (!(buff=parse_macro(buff,0,ret_used))) return(0);
  337.         *buff++=M_END_MACRO;
  338.         generate_jmp(M_JMP,jmp,buff);
  339.         /*}}}  */
  340.         /*{{{  pop dummy vars*/
  341.         { int i;
  342.  
  343.           for (i=dummy-1;i>=0;i--)
  344.            { *buff++=M_POP_INT;
  345.              *buff++=(TOKEN)dummy_var(i);
  346.            }
  347.         }
  348.         /*}}}  */
  349.         /*{{{  get return value*/
  350.         *buff++=M_PUSH_INT;
  351.         *buff++=(TOKEN)return_var;
  352.         *buff++=M_POP_INT;
  353.         set_dest(buff++,dest,t);
  354.         /*}}}  */
  355.         break;
  356.       }
  357.       /*}}}  */
  358.      case PRE:
  359.       /*{{{  do the action first*/
  360.       {
  361.         /*{{{  push dummy vars*/
  362.         { int i;
  363.  
  364.           for (i=0;i<dummy;i++)
  365.            { *buff++=M_PUSH_INT;
  366.              *buff++=(TOKEN)dummy_var(i);
  367.            }
  368.         }
  369.         /*}}}  */
  370.         if (!(buff=parse_macro(buff,0,ret_used))) return(0);
  371.         /*{{{  pop dummy vars*/
  372.         { int i;
  373.  
  374.           for (i=dummy-1;i>=0;i--)
  375.            { *buff++=M_POP_INT;
  376.              *buff++=(TOKEN)dummy_var(i);
  377.            }
  378.         }
  379.         /*}}}  */
  380.         if (!(buff=rpt(get_full_token(),buff,dest,dummy,ret_used,t))) return(0);
  381.         break;
  382.       }
  383.       /*}}}  */
  384.      case COUNTER:
  385.       /*{{{  convert boolean to int*/
  386.       { TOKEN *x;
  387.  
  388.         /*{{{  set-counter dest 0*/
  389.         *buff++ = M_SET_COUNTER;
  390.         set_dest(buff++,dest,t);
  391.         *buff++ = 0;
  392.         /*}}}  */
  393.         if (!(buff=parse_cond(buff,dummy,ret_used))) return(0);
  394.         buff=generate_jmp(M_JMP_FALSE,x=buff,buff);
  395.         /*{{{  set-counter dest 1*/
  396.         *buff++ = M_SET_COUNTER;
  397.         *buff++ = (TOKEN) dest;
  398.         *buff++ = 1;
  399.         /*}}}  */
  400.         generate_jmp(M_JMP_FALSE,x,buff);
  401.         break;
  402.       }
  403.       /*}}}  */
  404.      case OPERATION:
  405.       /*{{{  operation*/
  406.         *buff++ = M_SET_COUNTER;
  407.         set_dest(buff++,dest,t);
  408.         if (tk_operation->place<0)
  409.          { if (tk_operation->length>1) goto error_code;
  410.            *buff++ = tk_operation->ops[0];
  411.          }
  412.         else
  413.            *buff++ = O_CALL_FIX+tk_operation->place+1;
  414.         break;
  415.       /*}}}  */
  416.      case OPCODE:
  417.       /*{{{  opcode*/
  418.       { *buff++ = M_SET_COUNTER;
  419.         set_dest(buff++,dest,t);
  420.         *buff++ = tk_key->num;
  421.         break;
  422.       }
  423.       /*}}}  */
  424.      case DECODE_BUFFER:
  425.       /*{{{  decode a position to a buffer-position*/
  426.       { int v1;
  427.         int v2;
  428.         tokens tok;
  429.  
  430.         if ((tok=name_to_var(get_full_token(),1,new_vars_enabled))==VARIABLE)
  431.            v1=tk_var->no;
  432.         else if (!(buff=rpt(tok,buff,v1=dummy_var(dummy),dummy+1,ret_used,t)))
  433.            return(0);
  434.         if ((tok=name_to_var(get_full_token(),1,new_vars_enabled))==VARIABLE)
  435.            v2=tk_var->no;
  436.         else if (!(buff=rpt(tok,buff,v2=dummy_var(dummy+1),dummy+2,ret_used,t)))
  437.            return(0);
  438.         *buff++=M_GET_BUFFER;
  439.         *buff++=(TOKEN)v1;
  440.         *buff++=(TOKEN)v2;
  441.         *buff++=M_POP_INT;
  442.         *buff++=(TOKEN)dest;
  443.         break;
  444.       }
  445.       /*}}}  */
  446.      case FOLD_SL:
  447.      case FOLD_EL:
  448.       /*{{{  get length of fold-comment-string*/
  449.         *buff++=M_FOLD_DATA;
  450.         *buff++=(op==FOLD_SL)?0:2;
  451.         set_dest(buff++,dest,t);
  452.         break;
  453.       /*}}}  */
  454.      case FOLD_M1:
  455.      case FOLD_M2:
  456.      case FOLD_M3:
  457.      case FOLD_M4:
  458.      case FOLD_S:
  459.      case FOLD_E:
  460.       /*{{{  get data from fold comment*/
  461.         if (!(buff=rpt(get_full_token(),buff,dummy_var(dummy),dummy+1,ret_used,t))) return(0);
  462.         *buff++=M_FOLD_DATA;
  463.         *buff++=(op==FOLD_M1)? 4:
  464.                 (op==FOLD_M2)? 5:
  465.                 (op==FOLD_M3)? 6:
  466.                 (op==FOLD_M4)? 7:
  467.                 (op==FOLD_S) ? 1:
  468.                                3;
  469.         *buff++=(TOKEN)dummy_var(dummy);
  470.         *buff++=M_POP_INT;
  471.         set_dest(buff++,dest,t);
  472.         break;
  473.       /*}}}  */
  474.      case FILETYPE:
  475.      case STORE_CHAR:
  476.      case READ_REPEAT:
  477.      case SET_ENTER:
  478.      case SET_S_ENTER:
  479.      case STORE_MARK:
  480.      case STORE_X:
  481.      case STORE_Y:
  482.       /*{{{  get data from origami*/
  483.         *buff++ = (token==FILETYPE)    ? M_FILETYP :
  484.                   (token==SET_ENTER)   ? M_ENTERED :
  485.                   (token==STORE_MARK)  ? M_STORE_MARK :
  486.                   (token==STORE_X)     ? M_POS_TO_COUNTER :
  487.                   (token==STORE_Y)     ? M_STORE_LINE_NO :
  488.                   (token==STORE_CHAR)  ? M_STORE_C :
  489.                   (token==READ_REPEAT) ? M_READ_REPEAT :
  490.                                          M_S_ENTERED;
  491.         set_dest(buff++,dest,t);
  492.         break;
  493.       /*}}}  */
  494.      case NUMBER:
  495.       /*{{{  M_SET_COUNTER dest value*/
  496.       { *buff++=M_SET_COUNTER;
  497.         set_dest(buff++,dest,t);
  498.         *buff++=(TOKEN)tk_val;
  499.         break;
  500.       }
  501.       /*}}}  */
  502.      case ADD:
  503.      case MINUS:
  504.      case MULT:
  505.      case DIV:
  506.      case MOD:
  507.       /*{{{  list of arguments*/
  508.       { token=get_full_token();
  509.         if (token!=BEGIN)
  510.          /*{{{  compiling the unary -*/
  511.          { if (op!=MINUS)
  512.               m_exit(M_WANTBEGIN);
  513.            if (!(buff=rpt(token,buff,dest,dummy,ret_used,t)))
  514.               return(0);
  515.            *buff++=M_INV_COUNTER;
  516.            set_dest(buff++,dest,t);
  517.            break;
  518.          }
  519.          /*}}}  */
  520.         if (!(buff=rpt(get_full_token(),buff,dest,dummy,ret_used,t))) return(0);
  521.         token=name_to_var(get_full_token(),0,new_vars_enabled);
  522.         do
  523.          /*{{{  code one argument from list*/
  524.          { check_length(buff);
  525.            switch (token)
  526.             { case COMMA: break;
  527.               case VARIABLE:
  528.                  if (tk_var->size==1)
  529.                   /*{{{  code: op var var*/
  530.                   { int x=tk_var->no;
  531.  
  532.                     /*{{{  code the operation*/
  533.                     switch (op)
  534.                      { /* MINUS uses the code for ADD too!!          */
  535.                        case MINUS: *buff++=M_INV_COUNTER;*buff++=(TOKEN)dest;
  536.                        case ADD:   *buff++=M_SUM_COUNTER;break;
  537.                        case MULT:  *buff++=M_MULT;break;
  538.                        case DIV:   *buff++=M_DIV;break;
  539.                        case MOD:   *buff++=M_MOD;break;
  540.                        default:    m_exit(M_CRASH);
  541.                      }
  542.                     /*}}}  */
  543.                     /*{{{  code arguments*/
  544.                     set_dest(buff++,dest,t);
  545.                     set_source(buff++,x,t);
  546.                     /*}}}  */
  547.                     if (op==MINUS) { *buff++=M_INV_COUNTER;*buff++=(TOKEN)dest; }
  548.                     break;
  549.                   }
  550.                   /*}}}  */
  551.               default:
  552.                  if (!(buff=rpt(token,buff,dummy_var(dummy),dummy+1,ret_used,t)))
  553.                     return(0);
  554.                  /*{{{  code the operation*/
  555.                  switch (op)
  556.                   { /* MINUS uses the code for ADD too!!          */
  557.                     case MINUS:
  558.                        *buff++=M_INV_COUNTER;*buff++=(TOKEN)dummy_var(dummy);
  559.                     case ADD:
  560.                        *buff++=M_SUM_COUNTER;break;
  561.                     case MULT:
  562.                        *buff++=M_MULT;break;
  563.                     case DIV:
  564.                        *buff++=M_DIV;break;
  565.                     case MOD:
  566.                        *buff++=M_MOD;break;
  567.                     default:
  568.                        m_exit(M_CRASH);
  569.                   }
  570.                  /*}}}  */
  571.                  *buff++=dest;
  572.                  *buff++=dummy_var(dummy);
  573.             }
  574.          }
  575.          /*}}}  */
  576.         while ((token=name_to_var(get_full_token(),1,new_vars_enabled))!=END);
  577.         break;
  578.       }
  579.       /*}}}  */
  580.      case MACRO:
  581.       /*{{{  code a one Token macro as it's value'*/
  582.         if (ustrlen(tk_string)==1)
  583.          /*{{{  code the integer value of a given character*/
  584.          { *buff++=M_SET_COUNTER;
  585.            *buff++=(TOKEN)dest;
  586.            *buff++=(TOKEN)tk_string[0];
  587.            break;
  588.          }
  589.          /*}}}  */
  590.         else
  591.            goto error_code;
  592.       /*}}}  */
  593.      case NAME:
  594.       /*{{{  code C-x statements*/
  595.         if (tk_string[0]=='C' && tk_string[1]=='-' && tk_string[3]=='\0')
  596.          { *buff++=M_SET_COUNTER;
  597.            *buff++=(TOKEN)dest;
  598.            *buff++=ctrl_c[tk_string[2]];
  599.            break;
  600.          }
  601.         else
  602.            goto error_code;
  603.       /*}}}  */
  604.      default:
  605.      error_code:
  606.         m_exit(M_NOVAR);
  607.    }
  608.   return(buff);
  609. }
  610. /*}}}  */
  611.  
  612. public TOKEN *parse_term(tokens token,TOKEN *buff,int dest,int dummy_base,boolean *ret_used)
  613. { DEST_DAT t;
  614.  
  615.   start_dest_handle(&t,dest,&buff,&dummy_base);
  616.   buff=rpt(token,buff,dest,dummy_base+1,ret_used,&t);
  617.   end_dest_handle(&t);
  618.  
  619.   return(buff);
  620. }
  621. /*}}}  */
  622. /*{{{  get_message*/
  623. public TOKEN *get_message(TOKEN *buff)
  624. {
  625.   tokens read=get_full_token();
  626.   TOKEN *x=tk_macro;
  627.  
  628.   if (read!=MACRO)
  629.    /*{{{  complex prompt ( ... ))*/
  630.    { if (read!=BEGIN)
  631.         m_exit(M_NOMESSAGE);
  632.      while ((read=get_full_token())!=END)
  633.       /*{{{  handle message entry*/
  634.         switch (read)
  635.          { case MACRO:
  636.             /*{{{  copy the string*/
  637.             { TOKEN *x;
  638.  
  639.               for (x=tk_macro;*x;*buff++ = *x++);
  640.               break;
  641.             }
  642.             /*}}}  */
  643.            case NUMBER:
  644.             /*{{{  code the character directly*/
  645.               *buff++=tk_val;
  646.               break;
  647.             /*}}}  */
  648.            case HISTORY:
  649.             /*{{{  put history code*/
  650.             *buff++=M_GET_HISTORY;
  651.             if ((*buff++=(TOKEN)name_to_history(get_full_token(),False))==(TOKEN)unknown_history)
  652.                m_exit(M_NOHISTORY);
  653.             break;
  654.             /*}}}  */
  655.            case COUNTER:
  656.             /*{{{  put var*/
  657.               *buff++ = M_INT_STRING;
  658.               if (!(buff=put_var(buff))) return(0);
  659.               break;
  660.             /*}}}  */
  661.            case NAME:
  662.             /*{{{  search for the message*/
  663.             { int msg_no;
  664.  
  665.               if ((msg_no=name2msg(tk_string))>=0)
  666.                { *buff++=(-msg_no);
  667.                  break;
  668.                }
  669.             }
  670.             /*}}}  */
  671.            default:
  672.               m_exit(M_WANTEND);
  673.          }
  674.       /*}}}  */
  675.    }
  676.    /*}}}  */
  677.   else
  678.      while (*x) *buff++ = *x++;
  679.   return(buff);
  680. }
  681. /*}}}  */
  682.